home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Resources / Developers / XAMPP 1.5.4 / Windows installer / xampp-win32-1.5.4-installer.exe / xampp / php / pear / File / Util.php < prev   
Encoding:
PHP Script  |  2005-09-26  |  12.8 KB  |  458 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * File::Util
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  10.  * that is available through the world-wide-web at the following URI:
  11.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  12.  * the PHP License and are unable to obtain it through the web, please
  13.  * send a note to license@php.net so we can mail you a copy immediately.
  14.  *
  15.  * @category    File
  16.  * @package     File
  17.  * @author      Michael Wallner <mike@php.net>
  18.  * @copyright   2004-2005 Michael Wallner
  19.  * @license     http://www.php.net/license/3_0.txt  PHP License 3.0
  20.  * @version     CVS: $Id: Util.php,v 1.21 2005/08/09 07:52:13 mike Exp $
  21.  * @link        http://pear.php.net/package/File
  22.  */
  23.  
  24. /**#@+
  25.  * Sorting Constants
  26.  */
  27. define('FILE_SORT_NONE',    0);
  28. define('FILE_SORT_REVERSE', 1);
  29. define('FILE_SORT_NAME',    2);
  30. define('FILE_SORT_SIZE',    4);
  31. define('FILE_SORT_DATE',    8);
  32. define('FILE_SORT_RANDOM',  16);
  33. /**#@-*/
  34.  
  35. /**#@+
  36.  * Listing Constants
  37.  */
  38. define('FILE_LIST_FILES',   1);
  39. define('FILE_LIST_DIRS',    2);
  40. define('FILE_LIST_DOTS',    4);
  41. define('FILE_LIST_ALL',     FILE_LIST_FILES | FILE_LIST_DIRS | FILE_LIST_DOTS);
  42. /**#@-*/
  43.  
  44. /**
  45.  * @ignore
  46.  */
  47. define('FILE_WIN32', defined('OS_WINDOWS') ? OS_WINDOWS : !strncasecmp(PHP_OS, 'win', 3));
  48.  
  49. /** 
  50.  * File_Util
  51.  *
  52.  * File and directory utility functions.
  53.  * 
  54.  * @access  public
  55.  * @static
  56.  */
  57. class File_Util
  58. {
  59.     /**
  60.      * Returns a string path built from the array $pathParts. Where a join 
  61.      * occurs multiple separators are removed. Joins using the optional 
  62.      * separator, defaulting to the PHP DIRECTORY_SEPARATOR constant.
  63.      * 
  64.      * @static
  65.      * @access  public 
  66.      * @param   array   $parts Array containing the parts to be joined
  67.      * @param   string  $separator The directory seperator
  68.      */
  69.     function buildPath($parts, $separator = DIRECTORY_SEPARATOR)
  70.     {
  71.         $qs = '/^'. preg_quote($separator, '/') .'+$/';
  72.         for ($i = 0, $c = count($parts); $i < $c; $i++) {
  73.             if (!strlen($parts[$i]) || preg_match($qs, $parts[$i])) {
  74.                 unset($parts[$i]);
  75.             } elseif (0 == $i) {
  76.                 $parts[$i] = rtrim($parts[$i], $separator);
  77.             } elseif ($c - 1 == $i) {
  78.                 $parts[$i] = ltrim($parts[$i], $separator);
  79.             } else {
  80.                 $parts[$i] = trim($parts[$i], $separator);
  81.             } 
  82.         } 
  83.         return implode($separator, $parts);
  84.     } 
  85.  
  86.     /**
  87.      * Returns a path without leading / or C:\. If this is not
  88.      * present the path is returned as is.
  89.      * 
  90.      * @static
  91.      * @access  public 
  92.      * @param   string  $path The path to be processed
  93.      * @return  string  The processed path or the path as is
  94.      */
  95.     function skipRoot($path)
  96.     {
  97.         if (File_Util::isAbsolute($path)) {
  98.             if (FILE_WIN32) {
  99.                 return substr($path, $path{3} == '\\' ? 4 : 3);
  100.             }
  101.             return ltrim($path, '/');
  102.         }
  103.         return $path;
  104.     } 
  105.  
  106.     /**
  107.      * Returns the temp directory according to either the TMP, TMPDIR, or 
  108.      * TEMP env variables. If these are not set it will also check for the 
  109.      * existence of /tmp, %WINDIR%\temp
  110.      * 
  111.      * @static
  112.      * @access  public 
  113.      * @return  string  The system tmp directory
  114.      */
  115.     function tmpDir()
  116.     {
  117.         if (FILE_WIN32) {
  118.             if (isset($_ENV['TEMP'])) {
  119.                 return $_ENV['TEMP'];
  120.             }
  121.             if (isset($_ENV['TMP'])) {
  122.                 return $_ENV['TMP'];
  123.             }
  124.             if (isset($_ENV['windir'])) {
  125.                 return $_ENV['windir'] . '\\temp';
  126.             }
  127.             if (isset($_ENV['SystemRoot'])) {
  128.                 return $_ENV['SystemRoot'] . '\\temp';
  129.             }
  130.             if (isset($_SERVER['TEMP'])) {
  131.                 return $_SERVER['TEMP'];
  132.             }
  133.             if (isset($_SERVER['TMP'])) {
  134.                 return $_SERVER['TMP'];
  135.             }
  136.             if (isset($_SERVER['windir'])) {
  137.                 return $_SERVER['windir'] . '\\temp';
  138.             }
  139.             if (isset($_SERVER['SystemRoot'])) {
  140.                 return $_SERVER['SystemRoot'] . '\\temp';
  141.             }
  142.             return '\temp';
  143.         }
  144.         if (isset($_ENV['TMPDIR'])) {
  145.             return $_ENV['TMPDIR'];
  146.         }
  147.         if (isset($_SERVER['TMPDIR'])) {
  148.             return $_SERVER['TMPDIR'];
  149.         }
  150.         return '/tmp';
  151.     }
  152.  
  153.     /**
  154.      * Returns a temporary filename using tempnam() and File::tmpDir().
  155.      * 
  156.      * @static
  157.      * @access  public 
  158.      * @param   string  $dirname Optional directory name for the tmp file
  159.      * @return  string  Filename and path of the tmp file
  160.      */
  161.     function tmpFile($dirname = null)
  162.     {
  163.         if (!isset($dirname)) {
  164.             $dirname = File_Util::tmpDir();
  165.         } 
  166.         return tempnam($dirname, 'temp.');
  167.     } 
  168.  
  169.     /**
  170.      * Returns boolean based on whether given path is absolute or not.
  171.      * 
  172.      * @static
  173.      * @access  public 
  174.      * @param   string  $path Given path
  175.      * @return  boolean True if the path is absolute, false if it is not
  176.      */
  177.     function isAbsolute($path)
  178.     {
  179.         if (preg_match('/(?:\/|\\\)\.\.(?=\/|$)/', $path)) {
  180.             return false;
  181.         } 
  182.         if (FILE_WIN32) {
  183.             return preg_match('/^[a-zA-Z]:(\\\|\/)/', $path);
  184.         }
  185.         return ($path{0} == '/') || ($path{0} == '~');
  186.     } 
  187.  
  188.     /**
  189.      * Get path relative to another path
  190.      *
  191.      * @static
  192.      * @access  public
  193.      * @return  string
  194.      * @param   string  $path
  195.      * @param   string  $root
  196.      * @param   string  $separator
  197.      */
  198.     function relativePath($path, $root, $separator = DIRECTORY_SEPARATOR)
  199.     {
  200.         $path = File_Util::realpath($path, $separator);
  201.         $root = File_Util::realpath($root, $separator);
  202.         $dirs = explode($separator, $path);
  203.         $comp = explode($separator, $root);
  204.         
  205.         if (FILE_WIN32) {
  206.             if (strcasecmp($dirs[0], $comp[0])) {
  207.                 return $path;
  208.             }
  209.             unset($dirs[0], $comp[0]);
  210.         }
  211.         
  212.         foreach ($comp as $i => $part) {
  213.             if (isset($dirs[$i]) && $part == $dirs[$i]) {
  214.                 unset($dirs[$i], $comp[$i]);
  215.             } else {
  216.                 break;
  217.             }
  218.         }
  219.          
  220.         return str_repeat('..' . $separator, count($comp)) . implode($separator, $dirs);
  221.     }
  222.  
  223.     /**
  224.      * Get real path (works with non-existant paths)
  225.      *
  226.      * @static
  227.      * @access  public
  228.      * @return  string
  229.      * @param   string  $path
  230.      * @param   string  $separator
  231.      */
  232.     function realPath($path, $separator = DIRECTORY_SEPARATOR)
  233.     {
  234.         if (!strlen($path)) {
  235.             return $separator;
  236.         }
  237.         
  238.         $drive = '';
  239.         if (FILE_WIN32) {
  240.             $path = preg_replace('/[\\\\\/]/', $separator, $path);
  241.             if (preg_match('/([a-zA-Z]\:)(.*)/', $path, $matches)) {
  242.                 $drive = $matches[1];
  243.                 $path  = $matches[2];
  244.             } else {
  245.                 $cwd   = getcwd();
  246.                 $drive = substr($cwd, 0, 2);
  247.                 if ($path{0} !== $separator{0}) {
  248.                     $path  = substr($cwd, 3) . $separator . $path;
  249.                 }
  250.             }
  251.         } elseif ($path{0} !== $separator) {
  252.             $path = getcwd() . $separator . $path;
  253.         }
  254.         
  255.         $dirStack = array();
  256.         foreach (explode($separator, $path) as $dir) {
  257.             if (strlen($dir) && $dir !== '.') {
  258.                 if ($dir == '..') {
  259.                     array_pop($dirStack);
  260.                 } else {
  261.                     $dirStack[] = $dir;
  262.                 }
  263.             }
  264.         }
  265.         
  266.         return $drive . $separator . implode($separator, $dirStack);
  267.     }
  268.  
  269.     /**
  270.      * Check whether path is in root path
  271.      *
  272.      * @static
  273.      * @access  public
  274.      * @return  bool
  275.      * @param   string  $path
  276.      * @param   string  $root
  277.      */
  278.     function pathInRoot($path, $root)
  279.     {
  280.         static $realPaths = array();
  281.         
  282.         if (!isset($realPaths[$root])) {
  283.             $realPaths[$root] = File_Util::realPath($root);
  284.         }
  285.         
  286.         return false !== strstr(File_Util::realPath($path), $realPaths[$root]);
  287.     }
  288.  
  289.     /**
  290.      * List Directory
  291.      * 
  292.      * The final argument, $cb, is a callback that either evaluates to true or
  293.      * false and performs a filter operation, or it can also modify the 
  294.      * directory/file names returned.  To achieve the latter effect use as 
  295.      * follows:
  296.      * 
  297.      * <code>
  298.      * <?php
  299.      * function uc(&$filename) {
  300.      *     $filename = strtoupper($filename);
  301.      *     return true;
  302.      * }
  303.      * $entries = File_Util::listDir('.', FILE_LIST_ALL, FILE_SORT_NONE, 'uc');
  304.      * foreach ($entries as $e) {
  305.      *     echo $e->name, "\n";
  306.      * }
  307.      * ?>
  308.      * </code>
  309.      * 
  310.      * @static
  311.      * @access  public
  312.      * @return  array
  313.      * @param   string  $path
  314.      * @param   int     $list
  315.      * @param   int     $sort
  316.      * @param   mixed   $cb
  317.      */
  318.     function listDir($path, $list = FILE_LIST_ALL, $sort = FILE_SORT_NONE, $cb = null)
  319.     {
  320.         if (!strlen($path) || !is_dir($path)) {
  321.             return null;
  322.         }
  323.         
  324.         $entries = array();
  325.         for ($dir = dir($path); false !== $entry = $dir->read(); ) {
  326.             if ($list & FILE_LIST_DOTS || $entry{0} !== '.') {
  327.                 $isRef = ($entry === '.' || $entry === '..');
  328.                 $isDir = $isRef || is_dir($path .'/'. $entry);
  329.                 if (    ((!$isDir && $list & FILE_LIST_FILES)   ||
  330.                          ($isDir  && $list & FILE_LIST_DIRS))   &&
  331.                         (!is_callable($cb) || 
  332.                             call_user_func_array($cb, array(&$entry)))) {
  333.                     $entries[] = (object) array(
  334.                         'name'  => $entry,
  335.                         'size'  => $isDir ? null : filesize($path .'/'. $entry),
  336.                         'date'  => filemtime($path .'/'. $entry),
  337.                     );
  338.                 }
  339.             }
  340.         }
  341.         $dir->close();
  342.         
  343.         if ($sort) {
  344.             $entries = File_Util::sortFiles($entries, $sort);
  345.         }
  346.         
  347.         return $entries;
  348.     }
  349.     
  350.     /**
  351.      * Sort Files
  352.      * 
  353.      * @static
  354.      * @access  public
  355.      * @return  array
  356.      * @param   array   $files
  357.      * @param   int     $sort
  358.      */
  359.     function sortFiles($files, $sort)
  360.     {
  361.         if (!$files) {
  362.             return array();
  363.         }
  364.         
  365.         if (!$sort) {
  366.             return $files;
  367.         }
  368.         
  369.         if ($sort === 1) {
  370.             return array_reverse($files);
  371.         }
  372.         
  373.         if ($sort & FILE_SORT_RANDOM) {
  374.             shuffle($files);
  375.             return $files;
  376.         }
  377.         
  378.         $names = array();
  379.         $sizes = array();
  380.         $dates = array();
  381.     
  382.         if ($sort & FILE_SORT_NAME) {
  383.             $r = &$names;
  384.         } elseif ($sort & FILE_SORT_DATE) {
  385.             $r = &$dates;
  386.         } elseif ($sort & FILE_SORT_SIZE) {
  387.             $r = &$sizes;
  388.         } else {
  389.             asort($files, SORT_REGULAR);
  390.             return $files;
  391.         }
  392.         
  393.         $sortFlags = array(
  394.             FILE_SORT_NAME => SORT_STRING, 
  395.             FILE_SORT_DATE => SORT_NUMERIC, 
  396.             FILE_SORT_SIZE => SORT_NUMERIC,
  397.         );
  398.         
  399.         foreach ($files as $file) {
  400.             $names[] = $file->name;
  401.             $sizes[] = $file->size;
  402.             $dates[] = $file->date;
  403.         }
  404.         
  405.         if ($sort & FILE_SORT_REVERSE) {
  406.             arsort($r, $sortFlags[$sort & ~1]);
  407.         } else {
  408.             asort($r, $sortFlags[$sort]);
  409.         }
  410.     
  411.         $result = array();
  412.         foreach ($r as $i => $f) {
  413.             $result[] = $files[$i];
  414.         }
  415.     
  416.         return $result;
  417.     }
  418.     
  419.     /**
  420.      * Switch File Extension
  421.      * 
  422.      * @static
  423.      * @access  public
  424.      * @return  string|array
  425.      * @param   string|array    $filename
  426.      * @param   string          $to new file extension
  427.      * @param   string          $from change only files with this extension
  428.      * @param   bool            $reverse change only files not having $from extension
  429.      */
  430.     function switchExt($filename, $to, $from = null, $reverse = false)
  431.     {
  432.         if (is_array($filename)) {
  433.             foreach ($filename as $key => $file) {
  434.                 $filename[$key] = File_Util::switchExt($file, $to, $from);
  435.             }
  436.             return $filename;
  437.         }
  438.         
  439.         if ($len = strlen($from)) {
  440.             $ext = substr($filename, -$len - 1);
  441.             $cfn = FILE_WIN32 ? 'strcasecmp' : 'strcmp';
  442.             if (!$reverse == $cfn($ext, '.'. $from)) {
  443.                 return $filename;
  444.             }
  445.             return substr($filename, 0, -$len - 1) .'.'. $to;
  446.         }
  447.         
  448.         if ($pos = strpos($filename, '.')) {
  449.             return substr($filename, 0, $pos) .'.'. $to;
  450.         }
  451.         
  452.         return $filename .'.'. $to;
  453.     }
  454.     
  455. }
  456.  
  457. ?>
  458.